
public class YVMasm extends YVM {
	
	int compteur_mess;
	
	public YVMasm() {
		super();
		compteur_mess = 0;
	}
	
	
	/* Generation */
	
	public void entete() {
		genererCommentaire();
		super.entete();
		
		genererLigne("extrn lirent:proc, ecrent:proc, ecrbool:proc, ecrch:proc, ligsuiv:proc");
		genererLigne(".model SMALL");
		genererLigne(".586");
		genererLigne("");
		
		genererLigne(".CODE");
		genererLigne("");
	}
	
	public void startupCode() {
		genererCommentaire();
		super.startupCode();
		
		genererLigne("debut :");
		genererLigne("STARTUPCODE");
		genererLigne("");
	}
	
	public void iadd() {
		genererCommentaire();
		super.iadd();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("add ax, bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void isub() {
		genererCommentaire();
		super.isub();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("sub ax, bx");
		genererLigne("push ax");
		genererLigne("");
	}	
	
	public void imul() {
		genererCommentaire();
		super.imul();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("imul bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void idiv() {
		genererCommentaire();
		super.idiv();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cwd");
		genererLigne("idiv bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void inot() {
		genererCommentaire();
		super.inot();
		
		genererLigne("pop ax");
		genererLigne("not ax");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void ineg() {
		genererCommentaire();
		super.ineg();
		
		genererLigne("pop bx");
		genererLigne("mov ax, 0");
		genererLigne("sub ax, bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void ior() {
		genererCommentaire();
		super.ior();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("or ax, bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void iand() {
		genererCommentaire();
		super.iand();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("and ax, bx");
		genererLigne("push ax");
		genererLigne("");
	}
	
	public void iinf() {
		genererCommentaire();
		super.iinf();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp ax, bx");
		genererLigne("jge $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	
	}
	
	public void isup() {
		genererCommentaire();
		super.isup();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp ax, bx");
		genererLigne("jge $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	}
	
	public void iinfegal() {
		genererCommentaire();
		super.iinfegal();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp ax, bx");
		genererLigne("jg $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	}
	
	public void isupegal() {
		genererCommentaire();
		super.isupegal();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp bx, ax");
		genererLigne("jg $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	}
	
	public void iegal() {
		genererCommentaire();
		super.iegal();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp ax, bx");
		genererLigne("jne $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	}
	
	public void idiff() {
		genererCommentaire();
		super.idiff();
		
		genererLigne("pop bx");
		genererLigne("pop ax");
		genererLigne("cmp ax, bx");
		genererLigne("je $+6");
		genererLigne("push -1");
		genererLigne("jmp $+4");
		genererLigne("push 0");
		genererLigne("");
	}
	
	
	public void iload(String ident) {
		genererCommentaire();
		super.iload(ident);
		
		int offset = getOffsetIdent(ident);
		if (offset >=0) 
			genererLigne("push word ptr [bp+" + offset + "]");
		else
			genererLigne("push word ptr [bp" + offset + "]");
		genererLigne("");
	}
	
	public void iconst(int entier) {
		genererCommentaire();
		super.iconst(entier);
		
		genererLigne("push word ptr " + entier);
		genererLigne("");
	}
	
	public void iconst(String constante_string) {
		genererCommentaire();
		super.iconst(constante_string);
		
		Constante constante = (Constante) getIdent(constante_string); // getConstante ?	
		genererLigne("push word ptr " + constante.getValeur());
		genererLigne("");
	}
	
	
	public void istore(String ident) {
		genererCommentaire();
		super.istore(ident);
		
		genererLigne("pop ax");

		if (getOffsetIdent(ident) >=0) 
			genererLigne("mov word ptr[bp+" + getOffsetIdent(ident) + "], ax");
		else
			genererLigne("mov word ptr[bp" + getOffsetIdent(ident) + "], ax");
		genererLigne("");
	}
	
	public void ifeq(int etiquette) {
		genererCommentaire();
		super.ifeq(etiquette);
		
		genererLigne("pop ax");
		genererLigne("cmp ax, 0");
		genererLigne("je " + etiquette);
		genererLigne("");
	}
	
	public void goto2(int etiquette) {
		genererCommentaire();
		super.goto2(etiquette);
		
		genererLigne("goto " + etiquette);
		genererLigne("");
	}
	
	public void ouvreBloc(int taille) {
		genererCommentaire();
		super.ouvreBloc(taille);

		genererLigne("enter "+taille+",0");
		/* Nawak
		genererLigne("mov bp,sp");
		genererLigne("sub sp," + taille);
		genererLigne("");*/
	}
	
	public void aLaLigne() {
		genererCommentaire();
		super.aLaLigne();
		
		genererLigne("call ligsuiv");
		genererLigne("");
	}
	
	public void ecrireChaine(String chaine) {
		genererCommentaire();
		super.ecrireChaine(chaine);
		
		genererLigne(".DATA");
		
		if (chaine.charAt(0) != '"') chaine = "\"" + chaine;
		
		if (chaine.charAt( chaine.length()-1 ) == '"') chaine = chaine.substring(0, chaine.length()-1);
		
		genererLigne("mess" + compteur_mess + " DB " + chaine + "$\"");
		genererLigne(".CODE");
		genererLigne("lea dx,mess" + compteur_mess);
		genererLigne("push dx");
		genererLigne("call ecrch");
		genererLigne("");
		
		compteur_mess++;
	}

	public void queue() {
		genererCommentaire();
		super.queue();
		
		genererLigne("nop");
		genererLigne("EXITCODE");
		genererLigne("End debut");
		genererLigne("");
	}
	
	public void ecrire() {
		genererCommentaire();
		super.ecrire();
		
		if (YakaConstants.TYPE_BOOLEEN == Yaka.expression.getType())
			genererLigne("call ecrbool");
		else
			genererLigne("call ecrent");
		
		genererLigne("");
	}
	
	public void lireEnt(String ident) {
		genererCommentaire();
		super.lireEnt(ident);
		if (getOffsetIdent(ident) >= 0)
			genererLigne("lea dx,[bp+" + getOffsetIdent(ident) + "]");
		else
			genererLigne("lea dx,[bp" + getOffsetIdent(ident) + "]");
		genererLigne("push dx");
		genererLigne("call lirent");
		genererLigne("");
	}
	
	public void iffauxCondition(int compteur){
		genererCommentaire();
		super.iffauxCondition(compteur);
		
		genererLigne("pop ax");
		genererLigne("cmp ax, 0");
		genererLigne("je SINON" + compteur);
		genererLigne("");
	}
	
	public void gotoCondition(int compteur){
		genererCommentaire();
		super.gotoCondition(compteur);
		
		genererLigne("jmp FSI" + compteur);
		genererLigne("");
	}
	
	public void gotoIteration(int compteur){
		genererCommentaire();
		super.gotoIteration(compteur);
		
		genererLigne("jmp FAIRE" + compteur);
		genererLigne("");
	}
	
	public void sinon(int compteur){
		genererCommentaire();
		super.sinon(compteur);
		
		genererLigne("SINON" + compteur + " :");
	}
	
	public void iffauxIteration(int compteur){
		genererCommentaire();
		super.iffauxIteration(compteur);
		
		genererLigne("pop ax");
		genererLigne("cmp ax, 0");
		genererLigne("je FAIT" + compteur);
		genererLigne("");
	}

	public void ireturn(int offset){
		genererCommentaire();
		super.ireturn(offset);
		genererLigne("pop ax");
		genererLigne("mov [bp+"+offset+"],ax");
	}
	
	public void fermebloc(int n){
		genererCommentaire();
		super.fermebloc(n);
		
		genererLigne("leave");
		genererLigne("ret "+n);
	}
	
	public void reserveRetour(String ident_string){
		genererCommentaire();
		super.reserveRetour(ident_string);
		
		Ident ident = getIdent(ident_string);
		
		if (ident.getNature() == Ident.FONCTION)
			genererLigne("sub sp,2");
	}


	
	public void fait(int compteur){
		genererCommentaire();
		super.fait(compteur);

		genererLigne("FAIT" + compteur + ":");
		genererLigne("");
	}
}